package wn.lizzy.liums.config;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * 主数据源配置
 * DataSourceConfiguration.java
 * @author cuilijian  2017年3月22日--下午4:42:57
 *
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
		entityManagerFactoryRef="entityManagerFactory",
		transactionManagerRef="transactionManager",
		basePackages= { "wn.lizzy.liums" })//设置dao（repo）所在位置
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableAsync
@EnableScheduling
	public class DataSourceConfiguration {
		@Resource
		private Environment env;
	  
	    @Autowired  
	    @Qualifier("MainDataSource")
	    private DataSource dataSource;  
	  
	    @Bean(name = "entityManager")  
	    @Primary  
	    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {  
	        return entityManagerFactory(builder).getObject().createEntityManager();  
	    }  
	  
	    @Bean(name = "entityManagerFactory")  
	    @Primary  
	    public LocalContainerEntityManagerFactoryBean entityManagerFactory (EntityManagerFactoryBuilder builder) {  
	        return builder  
	                .dataSource(new LazyConnectionDataSourceProxy(dataSource))  
	                .properties(getHibernateProperties(env.getProperty("primary.datasource.prefix")+".hibernate"))  
	                .packages(new String[] {"wn.lizzy.liums"}) //设置实体类所在位置  
	                .persistenceUnit("persistenceUnit")  
	                .build();  
	    }  
	  
	    @Bean(name = "transactionManager")  
	    @Primary  
	    PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {  
	        return new JpaTransactionManager(entityManagerFactory(builder).getObject());  
	    }  
	    
	    private Map<String, String> getHibernateProperties(String prefix) {  
	    	Map<String, String> propertiesMap = new HashMap<String, String>();
			propertiesMap.put("hibernate.connection.release_mode", "auto");
			propertiesMap.put("hibernate.bytecode.use_refection_optimizer", "true");
			propertiesMap.put("hibernate.bytecode.provider", "cglib");
			propertiesMap.put("hibernate.current_session_context_class", "thread");

			propertiesMap.put("hibernate.max_fetch_depth", "1");
			propertiesMap.put("hibernate.default_batch_fetch_size", "100");
			propertiesMap.put("hibernate.jdbc.fetch.size", "30");
			propertiesMap.put("hibernate.jdbc.batch_size", "50");

			propertiesMap.put("hibernate.dialect", env.getProperty(prefix+".dialect"));
			propertiesMap.put("hibernate.show_sql", env.getProperty(prefix+".show-sql"));
			propertiesMap.put("hibernate.format_sql", env.getProperty(prefix+".format_sql"));
			propertiesMap.put("hibernate.hbm2ddl.auto", env.getProperty(prefix+".hbm2ddl.auto"));
			// 二级缓存
			propertiesMap.put("hibernate.cache.use_second_level_cache",env.getProperty(prefix+".use_second_level_cache"));
			// 查询缓存
			propertiesMap.put("hibernate.cache.use_query_cache", env.getProperty(prefix+".use_query_cache"));
			// 缓存实现
			propertiesMap.put("hibernate.cache.region.factory_class", org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory.class.getName());
			// 缓存配置
			propertiesMap.put("net.sf.ehcache.configurationResourceName", env.getProperty("liums.ehcache.url"));
	        return propertiesMap;  
	    } 
	}
